import logging
import time

from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint

from app.core.config import settings
from app.core.context import get_request_id, reset_current_request, set_current_request
from app.schemas.response import Response as CustomResponse

logger = logging.getLogger(__name__)


class RequestContextMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next: RequestResponseEndpoint):
        start_time = time.time()
        try:
            set_current_request(request)
            request_id = get_request_id()
            logger.info(f"Request started - [{request.method}]{request.url.path}")
            if settings.DEBUG:
                logger.debug(
                    f"Request headers: {request.headers} - Body: {await request.body()} - Query: {request.query_params}"
                )
            response = await call_next(request)
            process_time = time.time() - start_time
            logger.info(f"Request completed - ID: {request_id} - Time: {process_time:.3f}s")
            return response
        except Exception as e:
            logger.error(f"Request failed - ID: {get_request_id()} - Error: {str(e)}")
            return CustomResponse.error(message="Internal Server Error")
        finally:
            reset_current_request()
